﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Windows.Forms;
using System.Diagnostics;

namespace Nyx.Xna
{
    using XColor = Microsoft.Xna.Framework.Color;

    /// <summary>
    /// An Xna rendering control
    /// </summary>
    public abstract class XnaControl : GraphicsDeviceControl
    {
        Stopwatch deltaTime = new Stopwatch();
        Timer timer = new Timer();

        const int FPS = 60;

        /// <summary>
        /// Initializes a new instance of the <see cref="XnaControl"/> class.
        /// </summary>
        protected XnaControl() 
            : base()
        {
            this.MouseDown += new MouseEventHandler(this.HandleMouseDown);
        }

        /// <summary>
        /// Derived classes override this to draw themselves using the GraphicsDevice.
        /// </summary>
        protected override void Draw()
        {
            this.UpdateXna(this.GetElapsedTime());
            this.RenderXna(this.GetElapsedTime());
        }

        /// <summary>
        /// Derived classes override this to initialize their drawing code.
        /// </summary>
        protected override void Initialize()
        {
            timer.Interval = (int)((1f / FPS) * 1000);
            timer.Tick += new EventHandler(HandleTimerTick);
            timer.Start();
        }

        /// <summary>
        /// Renders the control.
        /// </summary>
        /// <param name="dt">The elapsed time since the previous render.</param>
        protected virtual void RenderXna(float dt)
        {
        }

        /// <summary>
        /// Updates the control.
        /// </summary>
        /// <param name="dt">The elapsed time since the previous update.</param>
        protected virtual void UpdateXna(float dt)
        {
        }

        float GetElapsedTime()
        {
            float elapsed = (float)deltaTime.Elapsed.TotalSeconds;
            deltaTime.Reset();
            deltaTime.Start();
            return elapsed;
        }

        void HandleMouseDown(object sender, MouseEventArgs e)
        {
            this.Select();
        }

        void HandleTimerTick(object sender, EventArgs e)
        {
            this.Invalidate();
            this.Update();
        }
    }
}
